package com.fesc.trade.demo.request;

import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.fesc.trade.demo.model.BaseModel;
import com.fesc.trade.demo.util.AssertUtil;

/**
 * 退款请求
 * @author prd-wfc
 * @version $Id: RefundRequest.java, v 0.1 2016年8月18日 下午8:47:44 prd-wfc Exp $
 */
public class RefundRequest extends BaseRequest {

    /**  */
    private static final long   serialVersionUID = 1L;

    private BizContent          bizContent       = new BizContent();

    private Map<String, String> paraMap          = new TreeMap<String, String>();

    @Override
    public void validate() {

        super.validate();

        AssertUtil.assertNotBlank(bizContent.merchantId, "merchant_id should not be NULL!");

        AssertUtil.assertNotBlank(bizContent.outTradeNo + bizContent.tradeNo, "out_trade_no and trade_no should not be NULL at the same time!");

        AssertUtil.assertNotBlank(bizContent.refundAmount, "refund_amount should not be NULL!");

    }

    public String getMerchantId() {
        return bizContent.merchantId;
    }

    public RefundRequest setMerchantId(String merchantId) {
        bizContent.merchantId = merchantId;
        return this;
    }

    public String getOutTradeNo() {
        return bizContent.outTradeNo;
    }

    public RefundRequest setOutTradeNo(String outTradeNo) {
        bizContent.outTradeNo = outTradeNo;
        return this;
    }

    public String getTradeNo() {
        return bizContent.tradeNo;
    }

    public RefundRequest setTradeNo(String tradeNo) {
        bizContent.tradeNo = tradeNo;
        return this;
    }

    public String getRefundAmount() {
        return bizContent.refundAmount;
    }

    public RefundRequest setRefundAmount(String refundAmount) {
        bizContent.refundAmount = refundAmount;
        return this;
    }

    public String getRefundReason() {
        return bizContent.refundReason;
    }

    public RefundRequest setRefundReason(String refundReason) {
        bizContent.refundReason = refundReason;
        return this;
    }

    public String getOutRequestNo() {
        return bizContent.outRequestNo;
    }

    public RefundRequest setOutRequestNo(String outRequestNo) {
        bizContent.outRequestNo = outRequestNo;
        return this;
    }

    public String getOperatorId() {
        return bizContent.operatorId;
    }

    public RefundRequest setOperatorId(String operatorId) {
        bizContent.operatorId = operatorId;
        return this;
    }

    public String getStoreId() {
        return bizContent.storeId;
    }

    public RefundRequest setStoreId(String storeId) {
        bizContent.storeId = storeId;
        return this;
    }

    public String getTerminalId() {
        return bizContent.terminalId;
    }

    public RefundRequest setTerminalId(String terminalId) {
        bizContent.terminalId = terminalId;
        return this;
    }

    public String getExternalInfo() {
        return bizContent.externalInfo;
    }

    public RefundRequest setExternalInfo(String externalInfo) {
        bizContent.externalInfo = externalInfo;
        return this;
    }

    public Map<String, String> buildParaMap() {
        super.setBizContent(bizContent.buildBizContentStr());

        if (StringUtils.isNotBlank(acquirerId)) {
            paraMap.put("acquirer_id", acquirerId);
        }
        if (StringUtils.isNotBlank(signType)) {
            paraMap.put("sign_type", signType);
        }
        if (StringUtils.isNotBlank(timestamp)) {
            paraMap.put("timestamp", timestamp);
        }
        if (StringUtils.isNotBlank(appAuthToken)) {
            paraMap.put("app_auth_token", appAuthToken);
        }
        if (StringUtils.isNotBlank(walletType)) {
            paraMap.put("wallet_type", walletType);
        }
        if (StringUtils.isNotBlank(super.bizContent)) {
            paraMap.put("biz_content", super.bizContent);
        }

        return paraMap;

    }

    /** 业务参数 */
    private static class BizContent extends BaseModel {

        /**  */
        private static final long serialVersionUID = 1L;

        // 商户识别号
        @JSONField(name = "merchant_id")
        private String            merchantId;

        // 订单支付时传入的商户订单号,不能和 trade_no同时为空。
        @JSONField(name = "out_trade_no")
        private String            outTradeNo;

        // 支付宝交易号，和商户订单号不能同时为空
        @JSONField(name = "trade_no")
        private String            tradeNo;

        // 需要退款的金额，该金额不能大于订单金额,单位为元，支持两位小数
        @JSONField(name = "refund_amount")
        private String            refundAmount;

        // 退款的原因说明
        @JSONField(name = "refund_reason")
        private String            refundReason;

        // 标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传
        @JSONField(name = "out_request_no")
        private String            outRequestNo;

        // 商户的操作员编号
        @JSONField(name = "operator_id")
        private String            operatorId;

        // 商户的门店编号
        @JSONField(name = "store_id")
        private String            storeId;

        // 商户的终端编号
        @JSONField(name = "terminal_id")
        private String            terminalId;

        // 扩展信息
        @JSONField(name = "external_info")
        private String            externalInfo;

        public String buildBizContentStr() {

            Map<String, Object> bizParaMap = new TreeMap<String, Object>();

            if (StringUtils.isNotBlank(merchantId)) {
                bizParaMap.put("merchant_id", merchantId);
            }
            if (StringUtils.isNotBlank(outTradeNo)) {
                bizParaMap.put("out_trade_no", outTradeNo);
            }
            if (StringUtils.isNotBlank(tradeNo)) {
                bizParaMap.put("trade_no", tradeNo);
            }
            if (StringUtils.isNotBlank(refundAmount)) {
                bizParaMap.put("refund_amount", refundAmount);
            }
            if (StringUtils.isNotBlank(refundReason)) {
                bizParaMap.put("refund_reason", refundReason);
            }
            if (StringUtils.isNotBlank(outRequestNo)) {
                bizParaMap.put("out_request_no", outRequestNo);
            }
            if (StringUtils.isNotBlank(operatorId)) {
                bizParaMap.put("operator_id", operatorId);
            }
            if (StringUtils.isNotBlank(storeId)) {
                bizParaMap.put("store_id", storeId);
            }
            if (StringUtils.isNotBlank(terminalId)) {
                bizParaMap.put("terminal_id", terminalId);
            }
            if (StringUtils.isNotBlank(externalInfo)) {
                bizParaMap.put("external_info", externalInfo);
            }

            return JSON.toJSONString(bizParaMap);
        }
    }
}
